package sample.stock;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.AndroidHttpTransport;

import sample.stock.model.Stock;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;

import com.csvreader.CsvReader;

public class StockApp extends Activity {
	private Button next = null;
	private Button update = null;
	private Spinner sp = null;
	private TextView ticker = null;
	private TextView open = null;
	private TextView high = null;
	private TextView low = null;
	private TextView close = null;
	private TextView volume = null;
	
	private static String SOAP_ACTION = "http://tempuri.org/GetAllTickers";
	private static final String NAMESPACE = "http://tempuri.org/";
	private static String METHOD_NAME = "GetAllTickers";
	private static final String URL = "http://10.0.2.2:2489/Service1.asmx";
	
	private ProgressDialog progressDialog;
	
    private EditText mDate;
    private Button mPickDate;
    private int mYear;
    private int mMonth;
    private int mDay;

    static final int DATE_DIALOG_ID = 0;
    
    private String open_price = "";
    private String high_price = "";
    private String low_price = "";
    private String close_price = "";
    private String volumes = "";
    
    // the callback received when the user "sets" the date in the dialog
    private DatePickerDialog.OnDateSetListener mDateSetListener =
    	new DatePickerDialog.OnDateSetListener() {
	    	@Override
	    	public void onDateSet(DatePicker view, int year, 
	    			int monthOfYear, int dayOfMonth) {
	    		mYear = year;
	    		mMonth = monthOfYear;
	    		mDay = dayOfMonth;
	    		updateDisplay();
	    	}
    };

    @Override
    protected Dialog onCreateDialog(int id) {
    	switch (id) {
    		case DATE_DIALOG_ID:
    			return new DatePickerDialog(this,
    					mDateSetListener,
    					mYear, mMonth, mDay);
    	}
    	return null;
    }
            
	@Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ticker = (TextView)findViewById(R.id.ticker);
        open = (TextView)findViewById(R.id.open);
        high = (TextView)findViewById(R.id.high);
        low = (TextView)findViewById(R.id.low);
        close = (TextView)findViewById(R.id.close);
        volume = (TextView)findViewById(R.id.volume);
        sp = (Spinner)findViewById(R.id.spinner1);
        
        // capture our View elements
        mDate = (EditText) findViewById(R.id.editText1);
        mPickDate = (Button) findViewById(R.id.button2);

        // add a click listener to the button
        mPickDate.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                showDialog(DATE_DIALOG_ID);
            }
        });

        // get the current date
        final Calendar c = Calendar.getInstance();
        mYear = c.get(Calendar.YEAR);
        mMonth = c.get(Calendar.MONTH);
        mDay = c.get(Calendar.DAY_OF_MONTH);

        // display the current date (this method is below)
        updateDisplay();
        
        progressDialog = new ProgressDialog(StockApp.this);
		progressDialog.setMessage("Loading...");
		new LoadSpinnerTask(progressDialog).execute();
        
        sp.setOnItemSelectedListener(new OnItemSelectedListener() {
			@Override
			public void onItemSelected(AdapterView<?> arg0, View arg1,
					int arg2, long arg3) {
				progressDialog = new ProgressDialog(StockApp.this);
				progressDialog.setMessage("Loading...");
				new LoadStockTask(progressDialog).execute();
			}

			@Override
			public void onNothingSelected(AdapterView<?> arg0) {
				Toast.makeText(getApplicationContext(), "Nothing selected", Toast.LENGTH_SHORT).show();
			}
		});
        
        next = (Button)findViewById(R.id.button1);
        next.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				progressDialog = new ProgressDialog(StockApp.this);
				progressDialog.setMessage("Loading...");
				new LoadDataTask(progressDialog).execute();
			}
		});
        
        update = (Button)findViewById(R.id.button3);
        update.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				/*if (sp.getCount()<1)
				{
					progressDialog = new ProgressDialog(StockApp.this);
					progressDialog.setMessage("Loading...");
					new LoadSpinnerTask(progressDialog).execute();
				}*/
				progressDialog = new ProgressDialog(StockApp.this);
				progressDialog.setMessage("Loading...");
				new LoadStockTask(progressDialog).execute();
			}
		});
    }
    
    private void updateDisplay() {
        String date = Integer.toString(mMonth+1) + "/" + Integer.toString(mDay) + "/" + Integer.toString(mYear);
        mDate.setText(date);
	}

	private class LoadStockTask  extends AsyncTask<Void, Void, Void> {
	  	  private ProgressDialog progress;
	  	  private Stock stock = null;
	  	  
	  	  public LoadStockTask(ProgressDialog progress) {
	  		    this.progress = progress;
	  		  }
	
	  		  public void onPreExecute() {
	  		    progress.show();
	  		  }
	
	  		  public void onPostExecute(Void unused) {
	  			  if(stock != null)
	  				DisplayStock(stock);
	  			  else
	  				  Toast.makeText(StockApp.this, "Data not found.", Toast.LENGTH_SHORT);
	  			  progress.dismiss();
	  		  }
	
			@SuppressWarnings("deprecation")
			@Override
	  		protected Void doInBackground(Void... arg0) {
				String ticker = sp.getSelectedItem().toString();
				String date = mDate.getText().toString();
				SOAP_ACTION = "http://tempuri.org/GetTickerByDate";
				METHOD_NAME = "GetTickerByDate";
	  				
	  			SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
	  			Request.addProperty("ticker", ticker); // replace by selected ticker in spinner
	  			Request.addProperty("date", date); // current date
	  		        
	  			SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
	  			soapEnvelope.dotNet = true;
	  			soapEnvelope.setOutputSoapObject(Request);
	  		        
	  			AndroidHttpTransport aht = new AndroidHttpTransport(URL);
	  			try{
	  				aht.call(SOAP_ACTION, soapEnvelope);
	  				SoapObject responseResult = (SoapObject)soapEnvelope.getResponse();
	  				SoapObject resultDataSet = (SoapObject)responseResult.getProperty(1);
	  				stock  = ParseSoapResponse_Stock(resultDataSet);
	  			}catch(Exception e){
	  				e.printStackTrace();
	  			}
	  			return null;
	  		}
    }
    
    private class LoadSpinnerTask  extends AsyncTask<Void, Void, Void> {
	  	  private ProgressDialog progress;
	  	  private String[] spinner = null;
	  	  
	  	  public LoadSpinnerTask(ProgressDialog progress) {
	  		    this.progress = progress;
	  		  }
	
	  		  public void onPreExecute() {
	  		    progress.show();
	  		  }
	
	  		  @SuppressWarnings("unchecked")
			public void onPostExecute(Void unused) {
	  			  if (spinner != null)
	  			 {
	  				  ArrayAdapter spinnerArrayAdapter = new ArrayAdapter(StockApp.this,
	  						  android.R.layout.simple_spinner_dropdown_item, spinner);
	 				 sp.setAdapter(spinnerArrayAdapter);
	  			 }
	  			  progress.dismiss();
	  		  }
	
			@SuppressWarnings("deprecation")
			@Override
	  		protected Void doInBackground(Void... arg0) {
				 SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
			        
				 SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
				 soapEnvelope.dotNet = true;
				 soapEnvelope.setOutputSoapObject(Request);
			        
				 AndroidHttpTransport aht = new AndroidHttpTransport(URL);
			        
				 try{
					 aht.call(SOAP_ACTION, soapEnvelope);
					 SoapObject responseResult = (SoapObject)soapEnvelope.getResponse();
					 spinner = ParseSoapResponse_Tickers(responseResult);
				 }catch(Exception e){
					 e.printStackTrace();
				 }
	  			return null;
	  		}
    }
    
    private class LoadDataTask  extends AsyncTask<Void, Void, Void> {
	  	  private ProgressDialog progress;
	  	  private List<Stock> stockPrices = new ArrayList<Stock>();
	  	  
	  	  public LoadDataTask(ProgressDialog progress) {
	  		    this.progress = progress;
	  		  }
	
	  		  public void onPreExecute() {
	  		    progress.show();
	  		  }
	
	  		  public void onPostExecute(Void unused) {
	  			  if(open_price != ""){
	  				Intent chartView = new Intent(StockApp.this, ChartView.class);
					chartView.putExtra("open_price", open_price);
					chartView.putExtra("high_price", high_price);
					chartView.putExtra("low_price", low_price);
					chartView.putExtra("close_price", close_price);
					chartView.putExtra("volumes", volumes);
					startActivity(chartView);
	  			  }
	  			  progress.dismiss();
	  		  }
	
			@SuppressWarnings("deprecation")
			@Override
	  		protected Void doInBackground(Void... arg0) {
					String ticker = sp.getSelectedItem().toString();
					// get the current date
			        final Calendar c = Calendar.getInstance();
			        int eYear = c.get(Calendar.YEAR);
			        int eMonth = c.get(Calendar.MONTH)+1;
			        int eDay = c.get(Calendar.DAY_OF_MONTH);
			        
					String endDate = eMonth + "/" + eDay + "/" + eYear; // current date
					String startDate = mDate.getText().toString();
					
					SOAP_ACTION = "http://tempuri.org/GetTickerPrices";
					METHOD_NAME = "GetTickerPrices";
						
					SoapObject Request = new SoapObject(NAMESPACE, METHOD_NAME);
					Request.addProperty("ticker", ticker);
					Request.addProperty("startDate", startDate);
					Request.addProperty("endDate", endDate);
	  		        
		  			SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
		  			soapEnvelope.dotNet = true;
		  			soapEnvelope.setOutputSoapObject(Request);
		  		        
		  			AndroidHttpTransport aht = new AndroidHttpTransport(URL);
		  			try{
		  				aht.call(SOAP_ACTION, soapEnvelope);
		  				SoapObject responseResult = (SoapObject)soapEnvelope.getResponse();
		  				SoapObject resultDataSet = (SoapObject)responseResult.getProperty(1);
		  				stockPrices = ParseSoapResponse_Stocks(resultDataSet);
		  				for(int i=0; i<stockPrices.size();i++){
		  					open_price += stockPrices.get(i).open + ",";
		  					high_price += stockPrices.get(i).high + ",";
		  					low_price += stockPrices.get(i).low + ",";
		  					close_price += stockPrices.get(i).close + ",";
		  					volumes += stockPrices.get(i).volume + ",";
		  				}
		  				open_price = open_price.substring(0,open_price.length()-1);
		  				high_price = open_price.substring(0,high_price.length()-1);
		  				low_price = open_price.substring(0,low_price.length()-1);
		  				close_price = open_price.substring(0,close_price.length()-1);
		  				volumes = open_price.substring(0,volumes.length()-1);
		  			}catch(Exception e){
		  				e.printStackTrace();
		  			}
	  			return null;
	  		}
  }
  
   public List<Stock> ParseSoapResponse_Stocks(SoapObject result)
  {
  	String temp = result.toString();
  	temp = temp.replace("anyType", "");
  	temp = temp.replace("Table=","");
  	temp = temp.replace("NewDataSet=", "");
  	temp = temp.replace("{", "");
  	String[] elements = temp.split("\\}");
  	List<Stock> stockPrices = new ArrayList<Stock>();
  	for(int i=0; i<elements.length; i++)
  	{
  		if(elements[i].length()>2)
  		{
  			Stock stock = new Stock();
  			stock.ticker = elements[i].substring(elements[i].indexOf("ticker=")+7, 
  	  				elements[i].indexOf(";", elements[i].indexOf("ticker=")));
  			stock.date = elements[i].substring(elements[i].indexOf("date=")+5, 
  	  				elements[i].indexOf(";", elements[i].indexOf("date=")));
  	  		stock.open = elements[i].substring(elements[i].indexOf("open_price=")+11, 
  	      			elements[i].indexOf(";", elements[i].indexOf("open_price=")));
  	  		stock.high = elements[i].substring(elements[i].indexOf("high_price=")+11, 
  	      			elements[i].indexOf(";", elements[i].indexOf("high_price=")));
  	  		stock.low = elements[i].substring(elements[i].indexOf("low_price=")+10, 
  	      			elements[i].indexOf(";", elements[i].indexOf("low_price=")));
  	  		stock.close = elements[i].substring(elements[i].indexOf("close_price=")+11, 
  	      			elements[i].indexOf(";", elements[i].indexOf("close_price=")));
  	  		stock.volume = elements[i].substring(elements[i].indexOf("volume=")+6, 
  	      			elements[i].indexOf(";", elements[i].indexOf("volume=")));
  	  		stockPrices.add(stock);
  		}
  	}
  	
  	return stockPrices;
  }

    public String[] ParseSoapResponse_Tickers(SoapObject result)
    {
    	String temp = result.toString();
    	temp = temp.substring(8);
    	temp = temp.replaceAll(" ", "");
    	temp = temp.replace("}", "");
    	String[] tickers = temp.split(";"); 
    	String[] spTickers = new String[tickers.length];
    	for(int i=0; i<tickers.length; i++)
    	{
    		spTickers[i] = tickers[i].substring(7);
    	}
    	return spTickers;
    }
    
    public Stock ParseSoapResponse_Stock(SoapObject result)
    {
    	String temp = result.toString();
      	temp = temp.replace("anyType", "");
      	temp = temp.replace("Table=","");
      	temp = temp.replace("NewDataSet=", "");
      	temp = temp.replace("{", "");
    	
      	Stock stock = new Stock();
      	stock.ticker = temp.substring(temp.indexOf("ticker=")+7, 
      			temp.indexOf(";", temp.indexOf("ticker=")));
      	stock.date = temp.substring(temp.indexOf("date=")+5, 
      			temp.indexOf(";", temp.indexOf("date=")));
      	stock.open = temp.substring(temp.indexOf("open_price=")+11, 
      			temp.indexOf(";", temp.indexOf("open_price=")));
      	stock.high = temp.substring(temp.indexOf("high_price=")+11, 
      			temp.indexOf(";", temp.indexOf("high_price=")));
      	stock.low = temp.substring(temp.indexOf("low_price=")+10, 
      			temp.indexOf(";", temp.indexOf("low_price=")));
      	stock.close = temp.substring(temp.indexOf("close_price=")+12, 
      			temp.indexOf(";", temp.indexOf("close_price=")));
      	stock.volume = temp.substring(temp.indexOf("volume=")+7, 
      			temp.indexOf(";", temp.indexOf("volume=")));
    	
    	return stock;
    }
    
    public void DisplayStock(Stock s)
    {
    	ticker.setText(s.ticker);
    	open.setText(s.open);
    	high.setText(s.high);
    	low.setText(s.low);
    	close.setText(s.close);
    	volume.setText(s.volume);
    } 
    
    public void DisplayStock(Cursor c)
    {
        Toast.makeText(this, 
                "id: " + c.getString(0) + "\n" +
                "Ticker: " + c.getString(1) + "\n" +
                "Date: " + c.getString(2) + "\n" +
                "Open:  " + c.getString(3) + "\n" +
                "High:  " + c.getString(4) + "\n" +
                "Low:  " + c.getString(5) + "\n" +
                "Close:  " + c.getString(6) + "\n" +
                "Volume:  " + c.getString(7),
                Toast.LENGTH_LONG).show();        
    } 
    
    public void DownloadFromUrl(String DownloadUrl, String fileName) 
    {
    	try {
    			File root = android.os.Environment.getExternalStorageDirectory();               
    			File dir = new File (root.getAbsolutePath() + "/stocks");
    			if(dir.exists()==false) {
    				dir.mkdirs();
    			}

    			File file = new File(dir, fileName);

    			long startTime = System.currentTimeMillis();
    			Log.d("DownloadManager", "download begining");
    			Log.d("DownloadManager", "download url:" + DownloadUrl);
    			Log.d("DownloadManager", "downloaded file name:" + fileName);
    	           
    	         //create the new connection
    			HttpClient client = new DefaultHttpClient();
                HttpGet request = new HttpGet();
                request.setURI(new URI(DownloadUrl));
                HttpResponse response = client.execute(request);
                
 	            //this will be used in reading the data from the internet
 	            InputStream inputStream = response.getEntity().getContent();

 	            //variable to store total downloaded bytes
 	            int downloadedSize = 0;
 	           
                //this will be used to write the downloaded data into the file we created
    	        FileOutputStream fileOutput = new FileOutputStream(file);
    	        
    	        //create a buffer...
 	            byte[] buffer = new byte[1024];
 	            int bufferLength = 0; //used to store a temporary size of the buffer

   	            //now, read through the input buffer and write the contents to the file
 	            while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
 	                   //add the data in the buffer to the file in the file output stream (the file on the sd card
 	                   fileOutput.write(buffer, 0, bufferLength);
 	                   //add up the size so we know how much is downloaded
 	                   downloadedSize += bufferLength;
 	            }
 	            //close the output stream when done
 	            fileOutput.close();
    	         
 	            Log.d("DownloadManager", "download ready in" + ((System.currentTimeMillis() - startTime) / 1000) + " sec");
 	            Log.d("DOwnloadManager", "download size" + downloadedSize);
 	            Context ctx = getApplicationContext();
 	            Toast.makeText(ctx, "DONE", Toast.LENGTH_SHORT).show();

    	   } catch (IOException e) {
    	       Log.d("DownloadManager", "Error: " + e);
    	   } catch (URISyntaxException e) {
    		   Log.d("DownloadManager", "Error: " + e);
    		   e.printStackTrace();
		}

    	}
	public void ReadCSV(String fileName)
	{
    	try {
    		File root = android.os.Environment.getExternalStorageDirectory();               
    		//File dir = new File (root.getAbsolutePath() + "/stocks");
			CsvReader products = new CsvReader(new FileReader(root.getAbsolutePath() + "/stocks/" + fileName));
			List<Stock> stockList = new ArrayList<Stock>();
			
			products.readHeaders();
			while (products.readRecord())
			{
				Stock newStock = new Stock();
				newStock.ticker = products.get("<Ticker>");
				newStock.date = products.get("<DTYYYYMMDD>");
				newStock.open = products.get("<Open>");
				newStock.high = products.get("<High>");
				newStock.low = products.get("<Low>");
				newStock.close = products.get("<Close>");
				newStock.volume = products.get("<Volume>");
				
				stockList.add(newStock);
			}
	
			products.close();
			
		} catch (FileNotFoundException e) {
			Context context = getApplicationContext();
    		CharSequence text = "File Not Found";
    		int duration = Toast.LENGTH_SHORT;
    		Toast toast = Toast.makeText(context, text, duration);
    		toast.show();
			e.printStackTrace();
		} catch (IOException e) {
			Context context = getApplicationContext();
    		CharSequence text = "IOException";
    		int duration = Toast.LENGTH_SHORT;
    		Toast toast = Toast.makeText(context, text, duration);
    		toast.show();
			e.printStackTrace();
		}
    }
}